﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcEngine.Blog.Repositories;
using MvcEngine.Blog.Models.Entities;
using MvcEngine.LinqToSqlProvider;
using MvcEngine.Core.Pagination;

namespace MvcEngine.Blog.LinqToSqlProvider
{
    public class BlogCategoryRepository : Repository, IBlogCategoryRepository
    {
        public IPagination<BlogCategory> GetAll(Guid blogId, int pageNumber, int count)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return (from c in contextManager.Context.Categories()
                        where c.BlogId == blogId
                        select c).AsPagination(pageNumber, count);
            }
        }

        public IList<BlogCategory> GetAllWithPublishedPosts(Guid blogId)
        {
            using (var contextManager = CreateContextManager(true))
            {
                var res = from pc in contextManager.Context.PostCategories()
                          join post in contextManager.Context.Posts() on pc.PostId equals post.Id
                          where post.PublishedDate.HasValue
                          select pc.CategoryId;

                return (from c in contextManager.Context.Categories()
                        where c.BlogId == blogId && res.Any(t => t == c.Id)
                        orderby c.CreatedDate
                        select c).ToList();
            }
        }

        public IList<BlogCategory> GetAllByPost(Guid postId)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return (from pc in contextManager.Context.PostCategories()
                 join post in contextManager.Context.Posts() on pc.PostId equals post.Id
                 join cat in contextManager.Context.Categories() on pc.CategoryId equals cat.Id
                 where post.Id == postId
                 select cat).ToList();
            }
        }

        public void DeleteAll(Guid blogId)
        {
            using (var contextManager = CreateContextManager(false))
            {
                contextManager.Context.Categories().DeleteAllOnSubmit(GetAll(blogId, 0, 0).ToList());
                contextManager.Commit();
            }
        }

        public BlogCategory Get(Guid blogId, string categorySlug)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return contextManager.Context.Categories().SingleOrDefault(c => c.BlogId == blogId && c.Slug == categorySlug);
            }
        }

        public BlogCategory Get(Guid id)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return contextManager.Context.Categories().SingleOrDefault(c => c.Id == id);
            }
        }

        public void Add(BlogCategory entity)
        {
            using (var contextManager = CreateContextManager(false))
            {
                contextManager.Context.Categories().InsertOnSubmit(entity);
                contextManager.Commit();
            }
        }

        public void Delete(Guid id)
        {
            using (var contextManager = CreateContextManager(false))
            {
                var category = contextManager.Context.Categories().SingleOrDefault(c => c.Id == id);
                if (category != null)
                {
                    contextManager.Context.Categories().DeleteOnSubmit(category);
                    contextManager.Commit();
                }
            }
        }

        public IList<BlogCategory> GetAll(Guid blogId)
        {
            using (var contextManager = CreateContextManager(true))
            {
                return contextManager.Context.Categories().Where(c => c.BlogId == blogId).ToList();
            }
        }

        public void Update(BlogCategory category)
        {
            using (var contextManager = CreateContextManager(false))
            {
                contextManager.Commit();
            }
        }
    }
}
